<template>
  <!-- 账号列表 -->
  <el-card>
    <!-- 1. 标题 -->
    <template #header>
      <h3 class="fs20">账号列表</h3>
    </template>

    <!-- 2. 表格
    ref="multipleTable"：vue用来获取表格元素
    :data="tableData"：表格数据
    @selection-change="handleSelectionChange"：表格所有选中的多选框数据 -->
    <el-table
      ref="multipleTable"
      :data="tableData"
      tooltip-effect="dark"
      style="width: 100%"
      @selection-change="handleSelectionChange"
      stripe
    >
      <el-table-column type="selection" width="55"> </el-table-column>
      <el-table-column label="账号" prop="account"></el-table-column>
      <el-table-column label="用户组" prop="userGroup"></el-table-column>
      <el-table-column label="创建时间" prop="ctime">
        <!-- 过滤器动态加载格式化后的时间 -->
        <template v-slot="{ row }">
          {{ row.ctime | formatTime }}
        </template>
      </el-table-column>
      <el-table-column label="操作">
        <!-- row：element提供的当前行的数据 -->
        <template v-slot="{ row }">
          <el-button type="primary" size="mini" @click="editUser(row)"
            >编辑</el-button
          >
          <el-button type="danger" size="mini" @click="delUser(row.id)"
            >删除</el-button
          >
        </template>
      </el-table-column>
    </el-table>

    <!-- 3. 分页
    :total="total"：数据总条数
    :current-page="currentPage"：默认当前页码
    :page-size="pageSize"：默认每页条数
    :page-sizes="[1, 2, 3, 4]"：改变每页条数的数组
    @size-change="handleSizeChange"：改变每页条数事件
    @current-change="handleCurrentChange"：改变当前页码事件 -->
    <el-pagination
      :total="total"
      :current-page="currentPage"
      :page-size="pageSize"
      :page-sizes="[1, 2, 3, 4]"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
      layout="total, sizes, prev, pager, next, jumper"
    >
    </el-pagination>

    <!-- 4. 按钮 -->
    <el-button type="danger" @click="batchDel()">批量删除</el-button>
    <el-button type="primary" @click="cancel()">取消选择</el-button>

    <!-- 5. 编辑对话框
    :visible.sync="dialogVisible"：对话框显示（true）、隐藏（false）
    center：内容居中 -->
    <el-dialog
      title="编 辑 账 号"
      :visible.sync="dialogVisible"
      width="30%"
      center
    >
      <!-- 5.1 对话框内容 -->
      <el-form :model="editForm" status-icon :rules="rules" ref="editForm">
        <!-- 账号 -->
        <el-form-item label="账号：" prop="uname">
          <el-input
            type="text"
            v-model="editForm.uname"
            autocomplete="off"
          ></el-input>
        </el-form-item>

        <!-- 用户组 -->
        <el-form-item label="用户组：">
          <el-select v-model="editForm.ugroup" clearable placeholder="请选择">
            <el-option label="普通管理员" value="普通管理员"></el-option>
            <el-option label="超级管理员" value="超级管理员"></el-option>
          </el-select>
        </el-form-item>
      </el-form>

      <!-- 5.2 对话框按钮 -->
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="editFished('editForm')"
          >确 定</el-button
        >
      </span>
    </el-dialog>
  </el-card>
</template>

<script>
import { userList, editUser, delUser, delUsers } from '@/api/users.js' // 账号列表、编辑账号、删除账号、批量删除账号请求
import { validateUname } from '@/utils/validate.js' // 表单验证
import moment from 'moment' // 日期格式化

export default {
  data() {
    return {
      /* 表格数据 */
      tableData: [], // 表格数据
      multipleSelection: [], // 表格所有选中的多选框数据

      /* 分页数据 */
      total: 0, // 数据总条数
      currentPage: 1, // 默认当前页码
      pageSize: 4, // 默认每页条数

      /* 编辑对话框数据 */
      dialogVisible: false, // 对话框显示（true）、隐藏（false）
      editId: 0, // 编辑当前row的id
      editForm: {
        uname: '', // 用户名
        ugroup: '' // 用户组
      },
      rules: {
        uname: [{ validator: validateUname, trigger: 'click' }]
      }
    }
  },

  methods: {
    /* 表格数据（账号列表接口请求回来的） */
    async getUserList() {
      /* 请求参数说明：
      currentPage：当前页码，init,
      pageSize：每页条数，init */

      /* 响应参数说明：
      total：数据总条数
      data：当前页码对应的数据（数组）
      id：数据唯一id
      ctime：账号创建的时间
      account：账号
      userGroup：用户组
      imgUrl：账号头像地址 */

      // 1. 发送账号列表请求
      const { total, data, id, ctime } = await userList({
        currentPage: this.currentPage,
        pageSize: this.pageSize
      })

      // 2. 渲染数据
      this.tableData = data // 表格数据
      this.total = total // 数据总条数
    },

    /* 表格所有选中的多选框数据 */
    handleSelectionChange(val) {
      this.multipleSelection = val
    },

    /* 表格方法 */
    /* 编辑 */
    editUser(row) {
      // 1. 显示对话框
      this.dialogVisible = true

      // 2. 复写数据
      this.editForm.uname = row.account // 账号
      this.editForm.ugroup = row.userGroup // 用户组

      // 3. 保存当前row的id
      this.editId = row.id
    },

    /* 编辑完成 */
    editFished(editForm) {
      // validate：el-form验证所有规则是否通过的方法，通过返回true，不通过返回false
      this.$refs[editForm].validate(async (valid) => {
        if (valid) {
          /* 请求参数说明：
          id：要修改账号的id，int
          account：账号，String
          userGroup：用户组，String */

          /* 响应参数说明：
          code：状态码，0代表成功，1代表失败，5001参数错误
          msg：提示信息 */

          // 1. 表单验证通过，发送编辑账号请求
          const { code, msg } = await editUser({
            id: this.editId,
            account: this.editForm.uname,
            userGroup: this.editForm.ugroup
          })

          if (code === 0) {
            // 2. 请求发送成功，提示信息
            this.$message.success({
              center: true,
              message: msg
            })

            // 3. 重新获取表格数据
            this.getUserList()

            // 4. 隐藏对话框
            this.dialogVisible = false
          } else {
            // 5. 请求发送失败，提示信息
            this.$message.error({
              center: true,
              message: msg
            })
          }
        } else {
          // 6. 表单验证不通过，提示信息
          this.$message.warning({
            center: true,
            message: '输入错误，请按照规则填写表单！'
          })
        }
      })
    },

    /* 删除 */
    delUser(id) {
      // 1. 点击删除按钮弹出confirm确认框
      this.$confirm('此操作将永久删除该账号, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })

        // 2. 确定
        .then(async () => {
          /* 请求参数说明：
          id：要删除账号的id，int */

          /* 响应参数说明：
          code：状态码，0代表成功，1代表失败，5001参数错误
          msg：提示信息 */

          // 3. 发起删除账号请求
          const { code, msg } = await delUser({ id })

          // 4. 判断状态码提示删除账号成功或失败
          if (code === 0) {
            // 5. 提示删除成功信息
            this.$message.success({
              message: msg,
              center: true
            })
          } else {
            // 6. 提示删除失败信息
            this.$message.error({
              message: msg,
              center: true
            })
          }

          // 7. 重新获取表格数据
          this.getUserList()
        })

        // 8. 取消
        .catch(() => {
          // 9. 提示取消信息
          this.$message.info({
            message: '已取消删除',
            center: true
          })
        })
    },

    /* 批量删除 */
    batchDel() {
      // 1. 点击删除按钮弹出confirm确认框
      this.$confirm('此操作将永久删除所有选中账号, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })

        // 2. 确定
        .then(async () => {
          /* 请求参数说明：
          ids：要删除数据的id组成的数组（字符串格式的数组："[1, 2, 3]"），String */

          /* 响应参数说明：
          code：状态码，0代表成功，1代表失败，5001参数错误
          msg：提示信息 */

          // 3. 获取请求参数
          const ids = []
          this.multipleSelection.forEach((v) => {
            ids.push(v.id)
          })

          /* 注意：后端逻辑请求参数ids为空数组时，服务器会挂掉 */
          // 4. 判断ids是否为空，不为空发起请求，为空提示信息
          if (ids.length) {
            // 5. 发起删除账号请求
            const { code, msg } = await delUsers({
              ids: JSON.stringify(ids) // 6. 处理参数格式：将数组转换成字符串数组
            })

            // 7. 判断状态码提示删除账号成功或失败
            if (code === 0) {
              // 8. 提示删除成功信息
              this.$message.success({
                message: msg,
                center: true
              })
            } else {
              // 9. 提示删除失败信息
              this.$message.error({
                message: msg,
                center: true
              })
            }

            // 10. 重新获取表格数据
            this.getUserList()
          } else {
            // 11. 提示取消信息
            this.$message.info({
              message: '还未选中账号，请选中账号后再删除',
              center: true
            })
          }
        })

        // 12. 取消
        .catch(() => {
          // 13. 提示取消信息
          this.$message.info({
            message: '已取消删除',
            center: true
          })
        })
    },

    /* 取消选择 */
    cancel(rows) {
      if (rows) {
        rows.forEach((row) => {
          this.$refs.multipleTable.toggleRowSelection(row)
        })
      } else {
        this.$refs.multipleTable.clearSelection()
      }
    },

    /* 分页方法 */
    /* 当前每页条数改变 */
    handleSizeChange(val) {
      // 1. 改变pageSize的值
      this.pageSize = val

      // 2. 重新获取表格数据
      this.getUserList()
    },

    /* 当前页码改变 */
    handleCurrentChange(val) {
      // 1. 改变currentPage的值
      this.currentPage = val

      // 2. 重新获取表格数据
      this.getUserList()
    }
  },

  created() {
    /* 数据创建后发起账号列表请求 */
    this.getUserList()
  },

  watch: {
    /* 监听编辑对话框的显示隐藏状态 */
    dialogVisible() {
      // 1. 当编辑对话框关闭时候，把表单重置
      if (!this.dialogVisible) {
        this.$refs.editForm.resetFields()
      }
    }
  },

  /* 过滤器 */
  filters: {
    // 1. 格式化时间
    formatTime(_) {
      return moment(_).format('YYYY-MM-DD HH:mm:ss')
    }
  }
}
</script>

<style lang="less" scoped>
.el-pagination {
  margin: 20px 0;
}

.el-select {
  width: 100%;
}

/deep/.el-dialog {
  min-width: 500px;
}
</style>
